package com.rd.p2p.app.account;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.qdlc.p2p.biz.adapted.AdaptedRechargeService;
import com.qdlc.p2p.dal.param.BindingCardReqestParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import com.opensymphony.xwork2.ModelDriven;
import com.qd.p2p.sina.pay.enums.BankCode;
import com.qd.p2p.sina.pay.enums.PayType;
import com.qd.p2p.sina.pay.response.BindingBankCardAdvanceResponse;
import com.qd.p2p.sina.pay.response.BindingBankCardResponse;
import com.qd.p2p.sina.pay.response.BlankResponse;
import com.qd.p2p.sina.pay.response.CreateHostingDepositResponse;
import com.qd.p2p.sina.service.SinaPayService;
import com.qdlc.p2p.biz.adapted.AdaptedServiceFactory;
import com.qdlc.p2p.biz.adapted.AdaptedWithdrawService;
import com.qdlc.p2p.biz.service.AccountBankService;
import com.qdlc.p2p.biz.service.AccountRechargeService;
import com.qdlc.p2p.biz.service.AccountService;
import com.qdlc.p2p.biz.service.BindingCardService;
import com.qdlc.p2p.biz.service.DictService;
import com.qdlc.p2p.biz.service.UserIdentifyService;
import com.qdlc.p2p.biz.service.UserService;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.biz.util.NotifyRequestUrl;
import com.qdlc.p2p.biz.util.UserLoginUtil;
import com.qdlc.p2p.biz.web.action.BaseAction;
import com.qdlc.p2p.common.constant.Constant;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.exception.AccountException;
import com.qdlc.p2p.common.util.DataUtils;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.NumberUtil;
import com.qdlc.p2p.common.util.SinaBase64;
import com.qdlc.p2p.common.util.SinaRSA;
import com.qdlc.p2p.common.util.ip.IPUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.dto.AccountBank;
import com.qdlc.p2p.dal.dto.AccountRecharge;
import com.qdlc.p2p.dal.dto.Dict;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.dto.UserIdentify;
import com.qdlc.p2p.dal.model.AccountBankModel;
import com.qdlc.p2p.dal.model.AccountCashModel;
import com.qdlc.p2p.dal.model.AccountRechargeModel;
import com.qdlc.p2p.dal.model.TppModel;
import com.qdlc.p2p.dal.util.UserTypeUtils;
import com.qdlc.p2p.dal.util.UserUtils;

public class AppPayAction extends BaseAction<AccountRechargeModel> implements ModelDriven<AccountRechargeModel> {

	private static final Logger log = Logger.getLogger(AppPayAction.class);

	private static final String SESSION_QUICKPAY_RESPONSE = "session_quickpay_response";
	private static final String SESSION_QUICKPAY_MONEY = "session_quickpay_money";
	private static final String SESSION_CUURENT_USER = "session_current_user";

	private static final String SESSION_BINDING_BANKCARD_TICKET = "binding_bankcard_ticket";
	private static final String SESSION_BINDING_BANKCARD_RESPONSE = "binding_bankcard_response";
    private static final String SESSION_BINDING_ACCOUNT_BANK = "binding_account_bank";

	@Resource
	private UserService userService;

	@Resource
	private AccountBankService accountBankService;

	@Resource
	private DictService dictService;

	@Autowired
	SinaPayService sinaPayService;

	@Autowired
	UserIdentifyService userIdentifyService;
	
	@Autowired
	AccountService accountService;
	
	AdaptedWithdrawService withdrawService = AdaptedServiceFactory.getService(AdaptedWithdrawService.class);

	@Autowired
	BindingCardService bindingCardService;

	@Autowired
	AccountRechargeService accountRechargeService;
	
	private Map<String, Object> data;

	//充值适配服务接口
	private AdaptedRechargeService adaptedRechargeService = AdaptedServiceFactory.getService(AdaptedRechargeService.class);

	/**
	 * 快捷支付，支付推进
	 *
	 * @author linya 2016-01-04
	 */
	@Action(value = "/app/pay/payAdvance")
	public void doPayAdvance() throws Exception {
		data = new HashMap<String, Object>();
		User user = getSessionUser();

		//检测充值前置条件
		ReturnResult result = adaptedRechargeService.rechargePreCondition(user, model.getMoney());
		if(result.isError()){
			printWebResCodeAndMsgResult("0",result.getErrorInfo());
			return;
		}

		//检测Token
		try {
			//checkToken("newRecharge");
		} catch (AccountException e) {
			 printWebResCodeAndMsgResult("0",e.getMessage());
			return;
		}

		//充值处理，成功则跳转到网银页面
		result = adaptedRechargeService.authRecharge(user, model.getMoney(), request);
		if(result.isSuccess()){
			String html = String.valueOf(result.getExtra("html"));
			this.printHtml(html);
		}else{
			printWebResCodeAndMsgResult("0",result.getErrorInfo());
			return;
		}
	}

	/**
	 * 绑定银行卡发短信
	 * 
	 * @throws IOException
	 * 
	 */
	@Action(value = "/app/pay/sendBindBankCode")
	public void sendBindBankCode() throws IOException {
		User user = getSessionUser();
		if (user == null) {
			printWebResCodeAndMsgResult("-1","用户尚未登录!");
			return;
		}
		BindingCardReqestParam bindingCardParam = populateBindingCardParam();
		ReturnResult result = bindingCardService.bindingBardForPhoneCode(user, bindingCardParam);
		if(result.isSuccess()){
			data = new HashMap<String, Object>();
			data.put("resCode","1");
			data.put("resMsg",result.getErrorInfo());
			data.put("ticket",result.getExtra("ticket"));
			printWebJson(getStringOfJpaObj(data));
		}else{
			printWebResCodeAndMsgResult("0",result.getErrorInfo());
		}
	}

	/**
	 * 用户绑定银行卡
	 * 
	 * @throws IOException
	 * 
	 */
	@Action(value = "/app/pay/tppBindBankCard")
	public void tppBindBankCard() throws Exception {
		User user = getSessionUser();
		String ticket = this.paramString("ticket");
		String phoneCode = this.paramString("code");
		BindingCardReqestParam bindingCardParam = populateBindingCardParam();
		ReturnResult result = bindingCardService.bindingBankCardAdvance(user, bindingCardParam, ticket, phoneCode);
		String resCode = result.isSuccess()? "1":"0";
		printWebResCodeAndMsgResult(resCode,result.getErrorInfo());
		return;
	}

	/**
	 * 提现信息
	 * 
	 * @return
	 */
	@Action(value="/app/pay/cashInfo")
	public void newCash() throws Exception {
		User user = getSessionUser();
		double  servFee = SystemConfigHelper.getDoubleValue(SystemConfigHelper.Nid.CASH_SERV_FEE);
		data = new HashMap<String, Object>();
		if (user == null) {
			printWebResCodeAndMsgResult("-1","用户尚未登录!");
			return;
		}
		long userId = user.getUserId();
		Account account = accountService.findAccountByUserId(userId);
		AccountBank accountBank = new AccountBank();
		TppModel tppModel = new TppModel();
		tppModel.setUser(user);
		TppBaseInterface tppService = TppServiceFactory.newIntance();
		List<AccountBankModel> bankList = tppService.tppQueryUserBankCardList(tppModel);
		for (AccountBankModel accountBankModel : bankList) {
			String picPath =  accountBankModel.getPicPath();
			picPath = picPath.replaceAll("mini", "weixin");
			accountBankModel.setPicPath(picPath);
		}
		AccountBankModel accountBankModel =  null;
		if(bankList !=null && bankList.size()!=0){
			accountBank = bankList.get(0);
			accountBankModel = AccountBankModel.instance(accountBank);
		}
		data.put("bankNum",  SystemConfigHelper.getIntegerValue(SystemConfigHelper.Nid.BANK_NUM));
		data.put("bankList", bankList);
		data.put("account", account);
		data.put("accountBank", accountBankModel);
		data.put("servFee",servFee);

//		BaseCash cash = new BaseCash();

		UserIdentify userIdentify = userIdentifyService.getUserIdentifyByUserId(user.getUserId());
//		data.put("validCash", cash.validCash(user, userIdentify, account,bankList));
		String cash_single_max_amount_limit =  SystemConfigHelper.getValue(SystemConfigHelper.Nid.CASH_SINGLE_MAX_AMOUNT_LIMIT);
		String cash_single_min_amount_limit =  SystemConfigHelper.getValue(SystemConfigHelper.Nid.CASH_SINGLE_MIN_AMOUNT_LIMIT);
		data.put("cash_single_max_amount_limit",cash_single_max_amount_limit);
		data.put("cash_single_min_amount_limit",cash_single_min_amount_limit);
		printWebJson(getStringOfJpaObj(data));
		return;
	}
	
	/**
     * 提现
     * @author hongbinglin 2016-01-06
     * @throws IOException 
     */
	@Action(value="/app/pay/withDraw")
	public void withDraw() throws Exception{
		// 获取当前用户信息
		User user = getSessionUser();
		if(user == null){
			printWebResCodeAndMsgResult("-1","用户尚未登录!");
			return;
		}
		String bankNo = paramString("bankNo");
		String payPwd = paramString("payPwd");
		double amount = paramDouble("amount");

		// 检测提取前置条件
		ReturnResult result = withdrawService.doCashPreCondition(user, amount, bankNo, payPwd);
		if(result.isError()){
			printWebResCodeAndMsgResult("0",result.getErrorInfo());
			return;
		}

		// 提现
		String ip = IPUtil.getRemoteIP(request);
		result = withdrawService.doWithdraw(user, bankNo, amount, ip);
		if(result.isError()){
			printWebResCodeAndMsgResult("0",result.getErrorInfo());
			return;
		}
		printWebResCodeAndMsgResult("1", "新浪已受理，请等待！");
		return;
	}
	
	/**
     * 银行卡绑定手机号码（升级功能，兼容以前用户）
     * @author hongbinglin 2016-01-06
     * @throws IOException 
     */
    @Action(value="/app/pay/bindPhone")
    public void bindCardResetPhone() throws IOException{
		// 获取当前的用户信息
		User userTest = getSessionUser();
		if (userTest == null) {
			printWebResCodeAndMsgResult("-1","用户尚未登录!");
			return;
		}

		UserIdentify userIdentify = UserLoginUtil.getUserIdentify();
		User user = userService.getCurrentSessionUser4Json(userIdentify);

		// 获取银行卡号和手机号码
		String bankNo = paramString("bankNo");
		String mobilePhone = paramString("mobilePhone");

		/*ReturnResult result = bindingCardService.bindingCardResetPhone(user, bankNo, mobilePhone);

		if(result.isSuccess()){
			Object ticket = result.getExtra(BindingCardServiceImpl.TICKET);
			Object accountBank = result.getExtra(BindingCardServiceImpl.ACCOUNT_BANK);
			session.put(SESSION_BINDING_BANKCARD_TICKET, ticket);
			session.put(SESSION_BINDING_ACCOUNT_BANK, accountBank);
			printWebResCodeAndMsgResult("1","获取手机验证码成功");
		}else{
			printWebResCodeAndMsgResult("0",result.getErrorInfo());
		}*/
    }
    
    /**
     * 银行卡绑定手机号码推进功能（升级功能，兼容以前用户）
     * @author linya 2016-01-06
     * @throws IOException 
     */
    @Action(value="/app/pay/bindPhone/advance")
    public void bindCardResetPhoneAdvance() throws IOException{
        data = new HashMap<String, Object>();
		// 获取当前的用户信息
		UserIdentify userIdentify = UserLoginUtil.getUserIdentify();
		User user = userService.getCurrentSessionUser4Json(userIdentify);
		// 获取手机验证码
		String phoneCode = paramString("code");
		// 获取ticket
		String ticket = DataUtils.toString(session.get(SESSION_BINDING_BANKCARD_TICKET));
		// 获取AccountBank
		AccountBank accountBank = (AccountBank)session.get(SESSION_BINDING_ACCOUNT_BANK);
		// 绑卡推进
	/*	ReturnResult result = bindingCardService.bindingCardResetPhoneAdvance(user, accountBank, phoneCode, ticket);
		printWebResult(result.getErrorInfo(), result.isSuccess());*/
        return;
    }
    
    /**
     * 检测账户是否绑定银行卡，如果绑定银行卡，检测是否绑定手机号码。
     * 
     * @throws IOException
     */
    @Action("/app/pay/checkBinding")
    public void hasBindingBank() throws IOException {
        User user = getSessionUser();
        data = new HashMap<String, Object>();
        if (user == null) {
			printWebResCodeAndMsgResult("-1","用户尚未登录!");
            return;
        }
        // 企业账户可以不进行绑卡验证
		if(UserTypeUtils.isInvestmentBorrow(user.getUserId())){
            printWebSuccess();
        } else {
            List<AccountBank> bankList = accountBankService.list(user.getUserId());
            if (CollectionUtils.isEmpty(bankList)) {
                data.put("resCode", "0");
                data.put("resMsg", "请绑定银行卡！");
                data.put("error_type", "no_bank");
                printWebJson(getStringOfJpaObj(data));
                return;
            }

            boolean bindPhone = false;
            for (AccountBank bank : bankList) {
                if (StringUtils.isNotEmpty(bank.getMobilephone())) {
                    bindPhone = true;
                    break;
                }
            }
            if (bindPhone) {
				printWebResCodeAndMsgResult("1","已绑定银行卡以及手机");
                return;
            } else {
                data.put("resCode", "0");
                data.put("resMsg", "请为银行卡绑定手机号码");
                data.put("error_type", "no_phone");
                printWebJson(getStringOfJpaObj(data));
                return;
            }
        }
    }

	/**
	 * 构建请求参数
	 * @return
	 */
	private BindingCardReqestParam populateBindingCardParam(){
		long dictBankId = paramLong("dictBankId");
		String province = paramString("province");
		String city = paramString("city");
		String bankNo = paramString("bankNo");
		String mobilephone = paramString("mobilephone");
		BindingCardReqestParam bindingCardParam = new BindingCardReqestParam();
		bindingCardParam.setDictBankId(dictBankId);
		bindingCardParam.setBankNo(bankNo);
		bindingCardParam.setMobilephone(mobilephone);
		bindingCardParam.setProvince(province);
		bindingCardParam.setCity(city);
		return bindingCardParam;
	}
}